import hmac
import hashlib
import base64
from functools import wraps
from ops.devops.utils.util_config import get_config
from ops.chatbot.cmds.cdnCmd import *
from ops.chatbot.cmds.deploy import *
from ops.chatbot.cmds.get_project import *
from ops.chatbot.cmds.domainCmd import *


# 装饰器，用于鉴权
def check(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        # 获取配置
        conf = get_config('dd')
        # 获取参数
        func_name = args[0]
        tmp_webhook = kwargs.get('tmp_webhook')
        senderId = kwargs.get('senderId')
        senderNick = kwargs.get('senderNick')

        # 非超管用户，只能运行普通命令

        if senderId not in conf.get('supers').split(',') and func_name not in conf.get('commands').split(','):
            msg = '用户:%s无权使用方法:%s，请联系管理员授权!' % (senderNick, func_name)
            SendMessage.send_text(tmp_webhook, msg)
            return msg
        return f(*args, **kwargs)
    return decorated


# 签名校验方法
def check_sign(*args, **kwargs):
    # 获取变量
    app_secret = kwargs.get('app_secret')
    timestamp = kwargs.get('timestamp')
    sign = kwargs.get('sign')
    tmp_webhook = kwargs.get('tmp_webhook')
    # print(app_secret, timestamp, sign)
    # 编码和校验
    app_secret_enc = app_secret.encode('utf-8')
    string_to_sign = '{}\n{}'.format(timestamp, app_secret)
    string_to_sign_enc = string_to_sign.encode('utf-8')
    hmac_code = hmac.new(app_secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
    sign_made = base64.b64encode(hmac_code).decode('utf-8')

    # 比较签名，不一致则返回403
    if sign_made != sign:
        msg = '非法请求！原因:签名校验失败'
        print(msg)
        SendMessage.send_text(tmp_webhook, msg)
        return {'code': 403, 'msg': f'{msg}'}
    return {'code': 0, 'sign': f'{sign}'}


# 调用实际方法
@check
def call_back(*args, **kwargs):

    conf = get_config('dd')

    # 从传参中获取函数名 参数和webhook地址等
    func_name = args[0]
    args = args[1:]
    tmp_webhook = kwargs.get('tmp_webhook')
    sender_id = kwargs.get('senderId')

    # 仅允许如下方法，否则返回提示信息
    if func_name not in conf.get('commands').split(','):
        msg = "方法使用错误，仅允许%s" % (conf.get('commands'))
        SendMessage.send_text(tmp_webhook, msg)
        return msg
    try:
        res = eval(func_name)(*args, webhook=tmp_webhook, sender_id=sender_id)
    except Exception as e:
        res = {"errCode": 400, "msg": "命令{0}执行失败，原因：{1}".format(func_name, e)}
    return res

